import React, { useCallback, useState } from 'react'
import { SchemaForm, Item, Submit, Reset, Observer, Layout, FormItemGrid } from '@amazebird/antd-schema-form'
import type { SchemaType } from '@amazebird/antd-schema-form'
import { Card, Button } from 'antd'

function isNumber(value) {
  return typeof value === 'number'
}

const itemProps = {
  style: { margin: '0 15px' },
  labelCol: { span: 0 },
  wrapperCol: { span: 20 }
}

// 商品卡片
function GoodCard() {
  const [color, setColor] = useState('#ccffb9')

  const onChange = useCallback((value) => {
    const color = value >= 0 ? '#ccffb9' : '#ffc3c3'
    setColor(color)
  }, [])
  const style = {
    minWidth: 220, margin: 10, height: 160, backgroundColor: color
  }

  return (
    <Card style={style}>
      <Item field="id" {...itemProps} />
      <FormItemGrid colCount={2}>

        <Item field="name" {...itemProps} />
        <Item field="price" {...itemProps} />
      </FormItemGrid>

      <Item
        field="stock"
        colon={false}
        onChange={onChange}
        labelCol={{ span: 10 }}
        wrapperCol={{ span: 14 }}
        style={{ margin: '0 15px', lineHeight: '50px' }} />
    </Card>
  )
}

const goodsData = [
  { id: '001', name: '咖啡', price: 18, stock: 20 },
  { id: '002', name: '奶茶', price: 12, stock: 50 },
  { id: '003', name: '可乐', price: 3, stock: 30 }
]

function getPrice(goodId) {
  const good = goodsData.find(({ id }) => id === goodId)
  return good?.price
}

function createOrderId() {
  return new Date().getTime()
}

async function getGoodlist() {
  return goodsData.map(({ id, name }) => ({ value: id, label: name }))
}

const schema: SchemaType = {
  goods: {
    type: 'array',
    value: () => goodsData,
    item: {
      type: 'object',
      fields: {
        id: {
          component: 'Text'
        },
        name: {
          component: ({ value }) => {
            return (
              <div style={{ fontSize: 15 }}>{value || ''}</div>
            )
          }
        },
        price: {
          component: ({ value }) => {
            return (
              <div style={{ fontSize: 18 }}>{value || ''}$</div>
            )
          }
        },
        stock: {
          label: '剩余库存',
          validOnChange: true,
          component: ({ value }) => {
            return (
              <div style={{ color: 'red', fontSize: 26 }}>{value}</div>
            )
          },
          value: Observer({
            watch: ['goods[].id', 'orders[*].items[*]'],
            filter: ([goodId]) => {
              return !!goodId
            },
            action: ([goodId, items = []]) => {
              const sum = items.reduce((pre, next) => {
                if (next.id === goodId && isNumber(next.num)) {
                  return pre + next.num
                }
                return pre
              }, 0)
              const good = goodsData.find(({ id }) => id === goodId)
              return good && (good.stock - sum)
            }
          }),
          rules: [{ min: 0, type: 'number', message: '库存不足' }]
        }
      }
    }
  },
  orders: {
    type: 'array',
    item: {
      type: 'object',
      fields: {
        order: {
          label: '订单号',
          component: 'Text',
          value: createOrderId
        },
        items: {
          type: 'array',
          item: {
            type: 'object',
            fields: {
              id: {
                component: 'Select',
                options: getGoodlist,
                required: [true, '请选择商品']
              },
              num: {
                component: 'InputNumber',
                required: [true, '请输入商品数量']
              },
              total: {
                label: '金额',
                component: ({ value }) => {
                  return <div>{value || 0} $</div>
                },
                value: Observer({
                  watch: ['./id', './num'],
                  action: ([id, num]) => {
                    const price = getPrice(id)
                    if(price) {
                      const total = price * num
                      return total
                    }
                  }
                })
              }
            }
          }
        },
        subtotal: {
          label: '小计',
          component: ({ value }) => {
            return <div>{value || 0} $</div>
          },
          value: Observer({
            watch: './items[*].total',
            action: (totals) => {
              return totals.reduce((pre, next = 0) => {
                return pre + next
              }, 0)
            }
          })
        },
        subcount: {
          label: '总量',
          component: 'Text',
          value: Observer({
            watch: './items[*].num',
            action: (nums) => {
              return nums.reduce((pre, next = 0) => {
                return pre + next
              }, 0)
            }
          })
        },
        total: {
          label: '总金额',
          component: 'Text'
        }
      }
    },
  }
}

const initialValues = {
  orders: [
    {
      'items': [
        {
          'total': 72,
          'id': '001',
          'num': 70
        }
      ],
      'order': 1638272664333,
      'subcount': 4,
      'subtotal': 72
    }
  ]
}

function GoodItem({ remove, index }) {
  return (
    <FormItemGrid colCount={4}>
      <Item field="id" wrapperCol={{ span: 24 }} />
      <Item field="num" wrapperCol={{ span: 24 }} />
      <Item field="total" />
      <Button onClick={() => remove(index)}>删除</Button>
    </FormItemGrid>
  )
}

function ComplicatedDemo() {
  const form = SchemaForm.createForm()

  const addGood = useCallback((index) => {
    const fieldPath = ['orders', index, 'items']
    const items = form.getFieldValue(fieldPath)
    items.push({})
    form.setFields([{ name: fieldPath, value: items }])
  }, [form])

  return (
    <SchemaForm form={form} schema={schema} defaultValues={{ goods: goodsData }} initialValues={initialValues}>
      <div style={{ textAlign: 'center' }}>
        <Item field="goods">
          {(fields: any) => {
            return (
              <div style={{ display: 'inline-flex', marginBottom: 8, alignItems: 'baseline' }}>
                {
                  // TODO: 类型优化
                  fields.map((field) => {
                    return (
                      <Item {...field}>
                        <GoodCard />
                      </Item>

                    )
                  })
                }
              </div>
            )
          }}
        </Item>
      </div>
      <div style={{ marginLeft: 120 }}>
        <Item field="orders">
          {(fields, { add }) => {
            return (
              <div>
                {
                  fields.map((field) => {
                    const { key, ...rest } = field
                    return (
                      <Item {...field} wrapperCol={{ span: 24 }}>
                        <FormItemGrid colCount={4}>
                          <Item field="order" />
                          <Item field="subcount" />
                          <Item field="subtotal" />
                          <Button onClick={() => addGood(rest.index)}>添加商品</Button>
                        </FormItemGrid>
                        <Item field="items" >
                          {(fields, { remove }) => {
                            return (
                              <>
                                {
                                  fields.map((field) => {
                                    return (
                                      <Item {...field} style={{ marginBottom: 0 }}>
                                        <GoodItem index={field.index} remove={remove} />
                                      </Item>

                                    )
                                  })
                                }
                              </>
                            )
                          }}
                        </Item>
                      </Item>
                    )
                  })
                }
                <Button onClick={() => add({ items: [{}] })}>添加订单</Button>
              </div>
            )
          }}
        </Item>
      </div>

      <Layout align="left" offset={8}>
        <Submit onFinish={(data) => { console.info(data) }} onError={(errors) => console.info(errors)} />
        <Reset />
      </Layout>
    </SchemaForm>
  )
}

export default ComplicatedDemo
